/**
 * jims
 */
package com.jims.master.modules.nurse.service;

import java.text.ParseException;
import java.util.*;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jims.master.common.utils.DateUtils;
import com.jims.master.common.utils.StringUtils;
import com.jims.master.modules.doctor.dao.PatVisitDao;
import com.jims.master.modules.doctor.entity.PatVisit;
import com.jims.master.modules.nurse.dao.*;
import com.jims.master.modules.nurse.entity.*;
import com.jims.master.modules.reg.utils.DateUtil;
import com.jims.master.modules.sys.dao.CompanyDao;
import com.jims.master.modules.sys.entity.Company;
import com.jims.master.modules.sys.entity.User;
import com.jims.master.modules.sys.utils.CompanyUtils;
import com.jims.master.modules.sys.utils.DictUtils;
import com.jims.master.modules.sys.utils.UserUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jims.master.common.service.CrudService;

/**
 * 辅助护理项目Service
 *
 * @author CTQ
 * @version 2017-06-01
 */
@Service
@Transactional(readOnly = true)
public class NurseTempInfoService extends CrudService<NurseTempInfoDao, NurseTempInfo> {
    @Autowired
    private NurseTempDetailInfoDao tempDetailInfoDao;
    @Autowired
    private PatVisitDao patVisitDao;
    @Autowired
    private NurseTempItemInfoDao itemInfoDao;
    @Autowired
    private NurseVitalSignsRecDao nurseVitalSignsRecDao;
    @Autowired
    private NewbornRecDao newbornRecDao;

    /**
     * 初始化项目信息
     * @param nurseTempInfo
     * @return
     */
    @Transactional(readOnly = false)
    public int saveTemp(NurseTempInfo nurseTempInfo) {
        int num = super.save(nurseTempInfo);
        List<NurseTempDetailInfo> list = handlerDetail(nurseTempInfo);
        if (list != null && list.size() > 0) {
            for (NurseTempDetailInfo i : list) {
                i.preInsert();
                i.updateOrgId();
                tempDetailInfoDao.insert(i);
            }
        }
        return num;
    }

    /**
     * 保存项目信息
     *
     * @param nurseTempInfo
     * @return
     */
    @Transactional(readOnly = false)
    public int saveInfo(NurseTempInfo nurseTempInfo) {
        int num = 0;
        String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        Date dates = DateUtils.parseDate(date);
        nurseTempInfo.setInspecttionDate(dates);
        nurseTempInfo.updateOrgId();
        num = super.save(nurseTempInfo);
        try {
            if (nurseTempInfo.getNurseTempDetailInfos() != null && nurseTempInfo.getNurseTempDetailInfos().size() > 0) {
                for (NurseTempDetailInfo i : nurseTempInfo.getNurseTempDetailInfos()) {
                    if (i.getTimePoint() != null) {
                        i.updateOrgId();
                        i.preUpdate();
                        if (i.getTimePoint() == 2) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 02:00:00", "yyyy-MM-dd HH:mm:ss"));
                        } else if (i.getTimePoint() == 6) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 06:00:00", "yyyy-MM-dd HH:mm:ss"));
                        } else if (i.getTimePoint() == 10) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 10:00:00", "yyyy-MM-dd HH:mm:ss"));
                        } else if (i.getTimePoint() == 14) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 14:00:00", "yyyy-MM-dd HH:mm:ss"));
                        } else if (i.getTimePoint() == 18) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 18:00:00", "yyyy-MM-dd HH:mm:ss"));
                        } else if (i.getTimePoint() == 22) {
                            i.setInspecttionDate(DateUtils.parseDate(date + " 22:00:00", "yyyy-MM-dd HH:mm:ss"));
                        }
                        tempDetailInfoDao.update(i);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return num;
    }

    public List<NurseTempItemInfo> findItemInfosWithItemDict(String infoId, String nurseGroups) {
        return findItemInfosWithItemDict(infoId, null, nurseGroups);
    }

    public List<NurseTempItemInfo> findItemInfosWithItemDict(String infoId, String deptId, String nurseGroups) {
        NurseTempItemInfo itemInfo = new NurseTempItemInfo();
        itemInfo.setOrgId(UserUtils.getOrgId());
        itemInfo.setItemDict(new NurseTempItemDict());
        //只查询当前登录人所在病区的数据
        itemInfo.getItemDict().setWardCode(deptId == null ? UserUtils.getUser().getOrgDept().getId() : deptId);
        //只查询当辅助护理项目的数据
        itemInfo.getItemDict().setClassCode("B");
        itemInfo.getItemDict().setNurseGroups(nurseGroups);
        itemInfo.setInfoId(infoId);
        return itemInfoDao.findListWithItemDict(itemInfo);
    }

    @Transactional(readOnly = false)
    public int saveItemInfo(NurseTempInfo nurseTempInfo) {
        int i = 0;
        if (nurseTempInfo != null && nurseTempInfo.getItemInfos() != null) {
            for (NurseTempItemInfo itemInfo : nurseTempInfo.getItemInfos()) {
                if (itemInfo.getIsNewRecord()) {
                    itemInfo.preInsert();
                    itemInfo.updateOrgId();
                    i = itemInfoDao.insert(itemInfo);
                } else {
                    itemInfo.preUpdate();
                    i = itemInfoDao.update(itemInfo);
                }
            }
        }
        if (nurseTempInfo != null && nurseTempInfo.getNurseTempDetailInfos() != null) {
            for (NurseTempDetailInfo detailInfo : nurseTempInfo.getNurseTempDetailInfos()) {
                detailInfo.preUpdate();
                i = tempDetailInfoDao.updateMajorInfo(detailInfo);
            }
        }
        return i;
    }

    @Transactional(readOnly = false)
    public int delete(NurseTempInfo nurseTempInfo) {
        return super.delete(nurseTempInfo);
    }

    /**
     * 三測單
     *
     * @param nurseTempInfo
     * @return
     */
    public Map generateInfo(NurseTempInfo nurseTempInfo) {
        List<NurseTempInfo> pTempInfoList = dao.findAllList(nurseTempInfo);
        PatVisit pv = patVisitDao.get(nurseTempInfo.getVisitId());

        NurseVitalSignsRec rec = new NurseVitalSignsRec();
        rec.setVisitId(nurseTempInfo.getVisitId());
        List<NurseVitalSignsRec> recs = nurseVitalSignsRecDao.findList(rec);
        List<NurseVitalSignsRec> out = new ArrayList<>();
        List<NurseVitalSignsRec> in = new ArrayList<>();
        for(NurseVitalSignsRec rec1 : recs) {
            if("转出".equals(rec1.getVitalSigns().trim())) {
                out.add(rec1);
            } else if("转入".equals(rec1.getVitalSigns().trim())) {
                in.add(rec1);
            }
        }
        Map map = null;
        // 日期
        List dateList = null;
        // 辅助护理值
        List<List<String>> itemInfoss = null;
        //辅助护理项目
        List<String> itemInfosTitle = null;

        List<NurseTempInfo> infos = null;
        int index = 0;
        Map<String, Map> m = new HashMap<>();
        for(int i = 0; index < pTempInfoList.size() ; i++){
            map = new HashMap();
            m.put("" + (i+1), map);
            dateList = new ArrayList();
            itemInfosTitle = new ArrayList<>();
            itemInfoss = new ArrayList<>();
            infos = new ArrayList<>();
            //基本信息
            map.put("jibenMap", pv);

            map.put("indate", DateUtils.formatDate(pv.getAdmissionDate(), "yyyy-MM-dd"));
            // 护理事件
            map.put("nurseEvent", recs);

            String outWardCode = null;
            String inWardCode = null;
            for (; index < pTempInfoList.size() && dateList.size() < 7; index++) {
                NurseTempInfo pTempInfo = pTempInfoList.get(index);
                infos.add(pTempInfo);
                if (pTempInfo.getInspecttionDate() != null) {
                    String date = DateUtils.formatDate(pTempInfo.getInspecttionDate(), "yyyy-MM-dd");
                    dateList.add(date);
                    //主要护理内容
                    NurseTempDetailInfo detailInfo = new NurseTempDetailInfo();
                    detailInfo.setTempInfoId(pTempInfo.getId());
                    List<NurseTempDetailInfo> detailInfos = tempDetailInfoDao.findList(detailInfo);
                    pTempInfo.setNurseTempDetailInfos(detailInfos);

                    if(outWardCode == null) {
                        for(NurseVitalSignsRec rec1 : out) {
                            if(date.equals(DateUtils.formatDate(rec1.getTimePoint()))) {
                                outWardCode = rec1.getWardCode();
                            }
                        }
                    }

                    if(outWardCode != null && inWardCode == null) {
                        for(NurseVitalSignsRec rec1 : in) {
                            if(date.equals(DateUtils.formatDate(rec1.getTimePoint()))) {
                                inWardCode = rec1.getWardCode();
                            }
                        }
                    }
                }
            }

            for(int j = 0; j < infos.size(); j++) {
                List<NurseTempItemInfo> itemInfos = findItemInfosWithItemDict(infos.get(j).getId(), outWardCode, "2");
                if(outWardCode != null && inWardCode != null && !outWardCode.equals(inWardCode)) {
                    itemInfos.addAll(findItemInfosWithItemDict(infos.get(j).getId(), inWardCode, "2"));
                }
                handlerItemInfos(itemInfosTitle, itemInfoss, itemInfos);
            }
            map.put("twdDateList", dateList);  //体温单日期集合
            map.put("tempInfoList", infos);
            map.put("itemInfosTitle", itemInfosTitle);
            map.put("itemInfos", itemInfoss);
        }

        return m;
    }

    /**
     * 三測單
     *
     * @param nurseTempInfo
     * @return
     */
    public Map generateChildInfo(NurseTempInfo nurseTempInfo) {
        List<NurseTempInfo> pTempInfoList = dao.findAllList(nurseTempInfo);
        PatVisit pv = patVisitDao.get(nurseTempInfo.getVisitId());

        NewbornRec newbornRec = new NewbornRec();
        newbornRec.setNewvisitId(nurseTempInfo.getVisitId());
        NewbornRec newborn = newbornRecDao.findList(newbornRec).get(0);

        NurseVitalSignsRec rec = new NurseVitalSignsRec();
        rec.setVisitId(nurseTempInfo.getVisitId());
        List<NurseVitalSignsRec> recs = nurseVitalSignsRecDao.findList(rec);
        List<NurseVitalSignsRec> out = new ArrayList<>();
        List<NurseVitalSignsRec> in = new ArrayList<>();
        for(NurseVitalSignsRec rec1 : recs) {
            if("转出".equals(rec1.getVitalSigns().trim())) {
                out.add(rec1);
            } else if("转入".equals(rec1.getVitalSigns().trim())) {
                in.add(rec1);
            }
        }
        Map map = null;
        // 日期
        List dateList = null;
        // 辅助护理值
        List<List<String>> itemInfoss = null;
        //辅助护理项目
        List<String> itemInfosTitle = null;

        List<NurseTempInfo> infos = null;
        int index = 0;
        Map<String, Map> m = new HashMap<>();
        for(int i = 0; index < pTempInfoList.size() ; i++){
            map = new HashMap();
            m.put("" + (i+1), map);
            dateList = new ArrayList();
            itemInfosTitle = new ArrayList<>();
            itemInfoss = new ArrayList<>();
            infos = new ArrayList<>();
            //基本信息
            map.put("jibenMap", pv);
            map.put("newborn", newborn);
            // 护理事件
            map.put("nurseEvent", recs);

            String outWardCode = null;
            String inWardCode = null;
            for (; index < pTempInfoList.size() && dateList.size() < 7; index++) {
                NurseTempInfo pTempInfo = pTempInfoList.get(index);
                infos.add(pTempInfo);
                if (pTempInfo.getInspecttionDate() != null) {
                    String date = DateUtils.formatDate(pTempInfo.getInspecttionDate(), "yyyy-MM-dd");
                    dateList.add(date);
                    //主要护理内容
                    NurseTempDetailInfo detailInfo = new NurseTempDetailInfo();
                    detailInfo.setTempInfoId(pTempInfo.getId());
                    List<NurseTempDetailInfo> detailInfos = tempDetailInfoDao.findList(detailInfo);
                    pTempInfo.setNurseTempDetailInfos(detailInfos);

                    if(outWardCode == null) {
                        for(NurseVitalSignsRec rec1 : out) {
                            if(date.equals(DateUtils.formatDate(rec1.getTimePoint()))) {
                                outWardCode = rec1.getWardCode();
                            }
                        }
                    }

                    if(outWardCode != null && inWardCode == null) {
                        for(NurseVitalSignsRec rec1 : in) {
                            if(date.equals(DateUtils.formatDate(rec1.getTimePoint()))) {
                                inWardCode = rec1.getWardCode();
                            }
                        }
                    }
                }
            }

            List<String> names = new ArrayList<>();
            List<NurseTempItemInfo> weight = new ArrayList<>();
            for(int j = 0; j < infos.size(); j++) {
                List<NurseTempItemInfo> itemInfos = findItemInfosWithItemDict(infos.get(j).getId(), outWardCode, "1");
                if(outWardCode != null && inWardCode != null && !outWardCode.equals(inWardCode)) {
                    itemInfos.addAll(findItemInfosWithItemDict(infos.get(j).getId(), inWardCode, "1"));
                }
                handlerItemInfos(itemInfosTitle, itemInfoss, itemInfos, weight);
                for(NurseTempItemInfo itemInfo : itemInfos) {
                    User user = itemInfo.getUpdateBy();
                    if(user != null) {
                        names.add(UserUtils.get(user.getId()).getName());
                        break;
                    }
                }
            }

            map.put("twdDateList", dateList);  //体温单日期集合
            map.put("tempInfoList", infos);
            map.put("itemInfosTitle", itemInfosTitle.size() > 9 ? itemInfosTitle.subList(0,9) : itemInfosTitle);
            map.put("itemInfos", itemInfoss.size() > 9 ? itemInfoss.subList(0,9) : itemInfoss);
            map.put("weight", weight);
            map.put("names", names);
        }

        return m;
    }

    private void handlerItemInfos(List<String> itemInfosTitle, List<List<String>> itemInfoss, List<NurseTempItemInfo> itemInfos) {
        handlerItemInfos(itemInfosTitle, itemInfoss, itemInfos, null);
    }

    /**
     * 处理辅助护理数据
     * @param itemInfosTitle 护理项目
     * @param itemInfoss 护理值
     * @param itemInfos
     */
    private void handlerItemInfos(List<String> itemInfosTitle, List<List<String>> itemInfoss, List<NurseTempItemInfo> itemInfos, List<NurseTempItemInfo> weight) {
        if(itemInfos != null && itemInfos.size() > 0) {
            boolean flag = itemInfoss.size() > 0 ? false : true;
            List<String> temp = null;
            int size = (itemInfoss.size() == 0 ? 0 : itemInfoss.get(0).size()) + 1;
            for(int i = 0; i < itemInfos.size(); i++) {
                NurseTempItemInfo itemInfo = itemInfos.get(i);
                if(weight != null && itemInfo.getItemDict().getVitalSigns().indexOf("体重") > -1) {
                    weight.add(itemInfo);
                }
                if(flag) {
                    if(temp == null) temp = new ArrayList<>();
                    String signs = itemInfo.getItemDict().getVitalSigns();
                    if(StringUtils.isNotBlank(itemInfo.getItemDict().getUnit())) {
                        signs += "(" + DictUtils.getDictLabel(itemInfo.getItemDict().getUnit(), "NURSE_ITEM_UNIT_DICT", "") + ")";
                    }
                    if(!temp.contains(itemInfo.getItemDict().getVitalSigns())) {
                        itemInfoss.add(new ArrayList<String>());
                        temp.add(itemInfo.getItemDict().getVitalSigns());
                        itemInfosTitle.add(signs);
                    }
                }
                for(int j = 0; j < itemInfosTitle.size(); j++) {
                    if(itemInfosTitle.get(j).startsWith(itemInfo.getItemDict().getVitalSigns())) {
                        if(itemInfoss.get(j).size() == size) {
                            if(StringUtils.isNotBlank(itemInfo.getItemValue())) {
                                itemInfoss.get(j).set(size - 1, itemInfo.getItemValue());
                            }
                        } else {
                            itemInfoss.get(j).add(itemInfo.getItemValue());
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * 初始化主要护理项目
     * @param nurseTempInfo
     * @return
     */
    private List<NurseTempDetailInfo> handlerDetail(NurseTempInfo nurseTempInfo) {
        int[] hours = {4, 8, 12, 16, 20, 24}; // 时间段
        List<NurseTempDetailInfo> list = Lists.newArrayList();
        NurseTempDetailInfo info = null;
        for(int hour : hours) {
            info = new NurseTempDetailInfo();
            info.setTempInfoId(nurseTempInfo.getId());
            info.setPatientId(nurseTempInfo.getPatientId());
            info.setVisitId(nurseTempInfo.getVisitId());
            info.setTimePoint(hour);
            list.add(info);
        }
        return list;
    }

}